﻿using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Xml;

namespace Comsenz.Base
{
    /// <summary>
    /// Comsenz XML 助理
    /// </summary>
    /// <author>Chiron</author>
    public static class XmlHelper
    {
        /// <summary>
        /// 序列化
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="htmlon"></param>
        /// <param name="isnormal"></param>
        /// <param name="level"></param>
        /// <returns></returns>
        public static string Serialize(IEnumerable<KeyValuePair<object, object>> arr, bool htmlon = false, bool isnormal = false, int level = 1)
        {
            var result = level == 1 ? "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n<root>\r\n" : string.Empty;
            if (arr != null)
            {
                var space = new string('\t', level);
                foreach (var obj in arr)
                {
                    if (obj.Value != null && obj.Value is IEnumerable<KeyValuePair<object, object>>)
                    {
                        result += space + "<item id=\"" + obj.Key + "\">\r\n" + Serialize(obj.Value as IEnumerable<KeyValuePair<object, object>>, htmlon, isnormal, level + 1) + space + "</item>\r\n";
                    }
                    else
                    {
                        result += space + "<item id=\"" + obj.Key + "\">" + (htmlon ? "<![CDATA[" : string.Empty) + (obj.Value ?? string.Empty) + (htmlon ? "]]>" : string.Empty) + "</item>\r\n";
                    }
                }
            }
            result = Regex.Replace(result, "([\x01-\x08\x0b-\x0c\x0e-\x1f])+", string.Empty);
            return level == 1 ? result + "</root>" : result;
        }

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="isnormal"></param>
        /// <returns></returns>
        public static Dictionary<object, object> UnSerialize(string xml, bool isnormal = false)
        {
            if (string.IsNullOrEmpty(xml)) return null;

            XmlNode node = null;
            try
            {
                var xDox = new XmlDocument();
                xDox.LoadXml(xml);
                node = xDox.SelectSingleNode("root");
            }
            catch { }
            return UnSerialize(node, isnormal);
        }

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="node"></param>
        /// <param name="isnormal"></param>
        /// <returns></returns>
        public static Dictionary<object, object> UnSerialize(XmlNode node, bool isnormal = false)
        {
            if (node == null) return null;

            var result = new Dictionary<object, object>();

            if (node != null && node.HasChildNodes)
            {
                foreach (XmlNode sNode in node.ChildNodes)
                {
                    try
                    {
                        var id = sNode.Attributes["id"].Value;
                        if (sNode.HasChildNodes)
                        {
                            if (sNode.ChildNodes.Count == 1 && sNode.ChildNodes[0] is XmlCDataSection)
                            {
                                result.Add(id, sNode.ChildNodes[0].Value);
                            }
                            else
                            {
                                result.Add(id, UnSerialize(sNode, isnormal));
                            }
                        }
                        else
                        {
                            result.Add(id, sNode.Value);
                        }
                    }
                    catch
                    { }
                }
            }
            return result;
        }
    }

}
